#include "streammanager.h"
#include <QUrl>
#include <QMessageBox>
#include <QSettings>
#include <QDebug>
#include <Phonon/BackendCapabilities>
#include <Phonon/AudioOutputDevice>

StreamManager::StreamManager(QObject* parent) : QObject(parent), streamIndex(-1) {
	QList<Phonon::AudioOutputDevice> out = Phonon::BackendCapabilities::availableAudioOutputDevices();
	qDebug() << out.size();
	foreach(Phonon::AudioOutputDevice d, out)
		qDebug() << d.name();
	qDebug() << Phonon::BackendCapabilities::availableMimeTypes();
	m_media = new Phonon::MediaObject(this);
	connect(m_media, SIGNAL(bufferStatus(int)), this, SLOT(onBufferStatus(int)));
	connect(m_media, SIGNAL(metaDataChanged()), this, SLOT(onMetaDataChanged()));
	connect(m_media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(onStateChanged(Phonon::State, Phonon::State)));
	audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);
	createPath(m_media, audioOutput);
	volumeWidget = new Phonon::VolumeSlider(audioOutput, 0);
	streams.insert("128k MP3", "http://www.radioparadise.com/musiclinks/rp_128.m3u");
	streams.insert("32k MP3", "http://www.radioparadise.com/musiclinks/rp_32.m3u");
	streams.insert("128k AAC", "http://www.radioparadise.com/musiclinks/rp_128aac.m3u");
	streams.insert("64k AAC", "http://www.radioparadise.com/musiclinks/rp_64aac.m3u");
	
	streamDownloader = new QNetworkAccessManager(this);
	connect(streamDownloader, SIGNAL(finished(QNetworkReply*)), this, SLOT(gotStream(QNetworkReply*)));
	
	updateStreamList();
}

void StreamManager::updateStreamList() {
	pause();
	streamIndex = -1;
	currentStreamAddresses.clear();
	QSettings settings;
	QUrl address(streams.value(settings.value("stream", "128k MP3").toString()));
	qDebug() << "fetching stream info from" << address;
	streamDownloader->get(QNetworkRequest(address));
}

void StreamManager::gotStream(QNetworkReply* reply) {
	bool error = reply->error() != QNetworkReply::NoError;

	if(!error) {
		currentStreamAddresses = QString(reply->readAll()).replace('\r', QChar()).split('\n', QString::SkipEmptyParts);
		qDebug() << "got addresses:" << currentStreamAddresses.size();
		if(!currentStreamAddresses.isEmpty()) {
			streamIndex = 0;
			foreach(QString a, currentStreamAddresses)
				qDebug() << a;
			emit(gotStream(true));
		}
	}
	else 
		qDebug() << "error getting stream info";  // FIXME handle error
}

void StreamManager::play(){
	if(streamIndex >= 0 && streamIndex < currentStreamAddresses.size()) {	
		QUrl url(currentStreamAddresses.at(streamIndex));
		qDebug() << "loading url" << url;
		//m_media->enqueue(QList<QUrl>() << url);
		m_media->setCurrentSource(Phonon::MediaSource(url));
		m_media->play();
		qDebug() << m_media->errorType() << m_media->errorString();

	}
	else
		QMessageBox::critical(0, "Error Playing Stream", "Error playing stream\n"+m_media->errorString());
}

void StreamManager::pause(){
	m_media->stop();
}

void StreamManager::onBufferStatus(int status) {
	qDebug() << "Buffering" << status << "%";
}

void StreamManager::onMetaDataChanged() {
	// radioparadise sends out both the song title and the artist in the title metadata field
	QStringList metadata = m_media->metaData(Phonon::TitleMetaData).join(" ").split("-", QString::SkipEmptyParts);
	QString fullText = metadata.join(" ");
	QString artist, title;
	if(fullText.indexOf("Radio Paradise") == -1) { // the first chunk of metadata is a description of the stream, we ignore it
		qDebug() << fullText;
		if(metadata.size() == 2) { // this is the expected size
			artist = metadata.at(0).trimmed();
			title = metadata.at(1).trimmed();
		}
		else if(metadata.size() == 1) { // assume there is no artist
			artist = "Unknown Arist";
			title = metadata.at(0).trimmed();
		}
		else if(metadata.size() >= 3) { // this can happen if the artist has a dash in the name
			// the artist's name is put together from the first two items
			// all remaining items go into the song title
			artist = QString(metadata.at(0)+"-"+metadata.at(1)).trimmed();
			title = metadata.at(2).trimmed();
			for(int i = 3; i < metadata.size(); i++)
				title += " "+metadata.at(i).trimmed();
		}
		else { // no title at all
			artist = "Unknown Arist";
			title = "Unknown Song";
		}
		emit(newSong(artist, title));
	}
}

QString StreamManager::stateToString(Phonon::State state) {
	QString stateString;
	if(state == Phonon::StoppedState)
		stateString = "Stopped";
	else if(state == Phonon::LoadingState)
		stateString = "Loading";
	else if(state == Phonon::PlayingState)
		stateString = "Playing";
	else if(state == Phonon::BufferingState)
		stateString = "Buffering";
	else if(state == Phonon::PausedState)
		stateString = "Paused";
	else if(state == Phonon::ErrorState)
		stateString = "Error";
	return stateString;
}

void StreamManager::onStateChanged(Phonon::State newState, Phonon::State oldState) {
	if(newState == Phonon::BufferingState)
		emit(buffering(0));
	else if(newState == Phonon::PlayingState)
		emit(buffering(100));
	
	QString newStateString = stateToString(newState);
	QString oldStateString = stateToString(oldState);
	qDebug() << "State changed from" << oldStateString << "to" << newStateString;
	qDebug() << m_media->errorType() << m_media->errorString();
	if(newState == Phonon::ErrorState) { // got an error, try the next stream in the list
		streamIndex++;
		play();
	}
}
